/*
    The I Ching (the Book of Changes) plasmoid.
    Copyright (C) 2002-2009 Jean Pierre Charalambos.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "hexagram.h"

Hexagram::Hexagram ( ) {
    inf = new Trigram();
    sup = new Trigram();
    generate();
    connect ( inf, SIGNAL ( changed() ), SLOT ( setId() ) );
    connect ( sup, SIGNAL ( changed() ), SLOT ( setId() ) );
}

Hexagram::Hexagram ( int anId ) {
    inf = new Trigram();
    sup = new Trigram();
    adjust ( anId );
    connect ( inf, SIGNAL ( changed() ), SLOT ( setId() ) );
    connect ( sup, SIGNAL ( changed() ), SLOT ( setId() ) );
}

Hexagram::Hexagram ( Trigram *i, Trigram *s ) {
    inf = i;
    sup = s;
    generate();
    connect ( inf, SIGNAL ( changed() ), SLOT ( setId() ) );
    connect ( sup, SIGNAL ( changed() ), SLOT ( setId() ) );
}

Hexagram::Hexagram ( Line * l1, Line * l2, Line * l3, Line * l4, Line * l5, Line * l6 ) {
    inf = new Trigram ( l1, l2, l3 );
    sup = new Trigram ( l4, l5, l6 );
    generate();
    connect ( inf, SIGNAL ( changed() ), SLOT ( setId() ) );
    connect ( sup, SIGNAL ( changed() ), SLOT ( setId() ) );
}

Hexagram::Hexagram ( QVector<int> vec ) {
    if ( vec.size() < 6 )
      vec.resize(6);
    Hexagram ( vec.at ( 0 ), vec.at ( 1 ), vec.at ( 2 ), vec.at ( 3 ), vec.at ( 4 ), vec.at ( 5 ) );
}

Hexagram::Hexagram ( int a, int b, int c, int d, int e, int f ) {
    inf = new Trigram ( a, b, c );
    sup = new Trigram ( d, e, f );
    generate();
    connect ( inf, SIGNAL ( changed() ), SLOT ( setId() ) );
    connect ( sup, SIGNAL ( changed() ), SLOT ( setId() ) );
}

void Hexagram::generate() {
    if ( inf->getId() ==1 && sup->getId() ==1 )
        id = 1;
    if ( inf->getId() ==1 && sup->getId() ==2 )
        id = 34;
    if ( inf->getId() ==1 && sup->getId() ==3 )
        id = 5;
    if ( inf->getId() ==1 && sup->getId() ==4 )
        id = 26;
    if ( inf->getId() ==1 && sup->getId() ==5 )
        id = 11;
    if ( inf->getId() ==1 && sup->getId() ==6 )
        id = 9;
    if ( inf->getId() ==1 && sup->getId() ==7 )
        id = 14;
    if ( inf->getId() ==1 && sup->getId() ==8 )
        id = 43;
    if ( inf->getId() ==2 && sup->getId() ==1 )
        id = 25;
    if ( inf->getId() ==2 && sup->getId() ==2 )
        id = 51;
    if ( inf->getId() ==2 && sup->getId() ==3 )
        id = 3;
    if ( inf->getId() ==2 && sup->getId() ==4 )
        id = 27;
    if ( inf->getId() ==2 && sup->getId() ==5 )
        id = 24;
    if ( inf->getId() ==2 && sup->getId() ==6 )
        id = 42;
    if ( inf->getId() ==2 && sup->getId() ==7 )
        id = 21;
    if ( inf->getId() ==2 && sup->getId() ==8 )
        id = 17;
    if ( inf->getId() ==3 && sup->getId() ==1 )
        id = 6;
    if ( inf->getId() ==3 && sup->getId() ==2 )
        id = 40;
    if ( inf->getId() ==3 && sup->getId() ==3 )
        id = 29;
    if ( inf->getId() ==3 && sup->getId() ==4 )
        id = 4;
    if ( inf->getId() ==3 && sup->getId() ==5 )
        id = 7;
    if ( inf->getId() ==3 && sup->getId() ==6 )
        id = 59;
    if ( inf->getId() ==3 && sup->getId() ==7 )
        id = 64;
    if ( inf->getId() ==3 && sup->getId() ==8 )
        id = 47;
    if ( inf->getId() ==4 && sup->getId() ==1 )
        id = 33;
    if ( inf->getId() ==4 && sup->getId() ==2 )
        id = 62;
    if ( inf->getId() ==4 && sup->getId() ==3 )
        id = 39;
    if ( inf->getId() ==4 && sup->getId() ==4 )
        id = 52;
    if ( inf->getId() ==4 && sup->getId() ==5 )
        id = 15;
    if ( inf->getId() ==4 && sup->getId() ==6 )
        id = 53;
    if ( inf->getId() ==4 && sup->getId() ==7 )
        id = 56;
    if ( inf->getId() ==4 && sup->getId() ==8 )
        id = 31;
    if ( inf->getId() ==5 && sup->getId() ==1 )
        id = 12;
    if ( inf->getId() ==5 && sup->getId() ==2 )
        id = 16;
    if ( inf->getId() ==5 && sup->getId() ==3 )
        id = 8;
    if ( inf->getId() ==5 && sup->getId() ==4 )
        id = 23;
    if ( inf->getId() ==5 && sup->getId() ==5 )
        id = 2;
    if ( inf->getId() ==5 && sup->getId() ==6 )
        id = 20;
    if ( inf->getId() ==5 && sup->getId() ==7 )
        id = 35;
    if ( inf->getId() ==5 && sup->getId() ==8 )
        id = 45;
    if ( inf->getId() ==6 && sup->getId() ==1 )
        id = 44;
    if ( inf->getId() ==6 && sup->getId() ==2 )
        id = 32;
    if ( inf->getId() ==6 && sup->getId() ==3 )
        id = 48;
    if ( inf->getId() ==6 && sup->getId() ==4 )
        id = 18;
    if ( inf->getId() ==6 && sup->getId() ==5 )
        id = 46;
    if ( inf->getId() ==6 && sup->getId() ==6 )
        id = 57;
    if ( inf->getId() ==6 && sup->getId() ==7 )
        id = 50;
    if ( inf->getId() ==6 && sup->getId() ==8 )
        id = 28;
    if ( inf->getId() ==7 && sup->getId() ==1 )
        id = 13;
    if ( inf->getId() ==7 && sup->getId() ==2 )
        id = 55;
    if ( inf->getId() ==7 && sup->getId() ==3 )
        id = 63;
    if ( inf->getId() ==7 && sup->getId() ==4 )
        id = 22;
    if ( inf->getId() ==7 && sup->getId() ==5 )
        id = 36;
    if ( inf->getId() ==7 && sup->getId() ==6 )
        id = 37;
    if ( inf->getId() ==7 && sup->getId() ==7 )
        id = 30;
    if ( inf->getId() ==7 && sup->getId() ==8 )
        id = 49;
    if ( inf->getId() ==8 && sup->getId() ==1 )
        id = 10;
    if ( inf->getId() ==8 && sup->getId() ==2 )
        id = 54;
    if ( inf->getId() ==8 && sup->getId() ==3 )
        id = 60;
    if ( inf->getId() ==8 && sup->getId() ==4 )
        id = 41;
    if ( inf->getId() ==8 && sup->getId() ==5 )
        id = 19;
    if ( inf->getId() ==8 && sup->getId() ==6 )
        id = 61;
    if ( inf->getId() ==8 && sup->getId() ==7 )
        id = 38;
    if ( inf->getId() ==8 && sup->getId() ==8 )
        id = 58;
}

void Hexagram::adjust ( int i ) {
    id = i-1;
    id = id%64;
    id ++;
    switch ( id ) {
    case 1:
        inf->adjust ( 1 );
        sup->adjust ( 1 );
        break;
    case 34:
        inf->adjust ( 1 );
        sup->adjust ( 2 );
        break;
    case 5:
        inf->adjust ( 1 );
        sup->adjust ( 3 );
        break;
    case 26:
        inf->adjust ( 1 );
        sup->adjust ( 4 );
        break;
    case 11:
        inf->adjust ( 1 );
        sup->adjust ( 5 );
        break;
    case 9:
        inf->adjust ( 1 );
        sup->adjust ( 6 );
        break;
    case 14:
        inf->adjust ( 1 );
        sup->adjust ( 7 );
        break;
    case 43:
        inf->adjust ( 1 );
        sup->adjust ( 8 );
        break;
    case 25:
        inf->adjust ( 2 );
        sup->adjust ( 1 );
        break;
    case 51:
        inf->adjust ( 2 );
        sup->adjust ( 2 );
        break;
    case 3:
        inf->adjust ( 2 );
        sup->adjust ( 3 );
        break;
    case 27:
        inf->adjust ( 2 );
        sup->adjust ( 4 );
        break;
    case 24:
        inf->adjust ( 2 );
        sup->adjust ( 5 );
        break;
    case 42:
        inf->adjust ( 2 );
        sup->adjust ( 6 );
        break;
    case 21:
        inf->adjust ( 2 );
        sup->adjust ( 7 );
        break;
    case 17:
        inf->adjust ( 2 );
        sup->adjust ( 8 );
        break;
    case 6:
        inf->adjust ( 3 );
        sup->adjust ( 1 );
        break;
    case 40:
        inf->adjust ( 3 );
        sup->adjust ( 2 );
        break;
    case 29:
        inf->adjust ( 3 );
        sup->adjust ( 3 );
        break;
    case 4:
        inf->adjust ( 3 );
        sup->adjust ( 4 );
        break;
    case 7:
        inf->adjust ( 3 );
        sup->adjust ( 5 );
        break;
    case 59:
        inf->adjust ( 3 );
        sup->adjust ( 6 );
        break;
    case 64:
        inf->adjust ( 3 );
        sup->adjust ( 7 );
        break;
    case 47:
        inf->adjust ( 3 );
        sup->adjust ( 8 );
        break;
    case 33:
        inf->adjust ( 4 );
        sup->adjust ( 1 );
        break;
    case 62:
        inf->adjust ( 4 );
        sup->adjust ( 2 );
        break;
    case 39:
        inf->adjust ( 4 );
        sup->adjust ( 3 );
        break;
    case 52:
        inf->adjust ( 4 );
        sup->adjust ( 4 );
        break;
    case 15:
        inf->adjust ( 4 );
        sup->adjust ( 5 );
        break;
    case 53:
        inf->adjust ( 4 );
        sup->adjust ( 6 );
        break;
    case 56:
        inf->adjust ( 4 );
        sup->adjust ( 7 );
        break;
    case 31:
        inf->adjust ( 4 );
        sup->adjust ( 8 );
        break;
    case 12:
        inf->adjust ( 5 );
        sup->adjust ( 1 );
        break;
    case 16:
        inf->adjust ( 5 );
        sup->adjust ( 2 );
        break;
    case 8:
        inf->adjust ( 5 );
        sup->adjust ( 3 );
        break;
    case 23:
        inf->adjust ( 5 );
        sup->adjust ( 4 );
        break;
    case 2:
        inf->adjust ( 5 );
        sup->adjust ( 5 );
        break;
    case 20:
        inf->adjust ( 5 );
        sup->adjust ( 6 );
        break;
    case 35:
        inf->adjust ( 5 );
        sup->adjust ( 7 );
        break;
    case 45:
        inf->adjust ( 5 );
        sup->adjust ( 8 );
        break;
    case 44:
        inf->adjust ( 6 );
        sup->adjust ( 1 );
        break;
    case 32:
        inf->adjust ( 6 );
        sup->adjust ( 2 );
        break;
    case 48:
        inf->adjust ( 6 );
        sup->adjust ( 3 );
        break;
    case 18:
        inf->adjust ( 6 );
        sup->adjust ( 4 );
        break;
    case 46:
        inf->adjust ( 6 );
        sup->adjust ( 5 );
        break;
    case 57:
        inf->adjust ( 6 );
        sup->adjust ( 6 );
        break;
    case 50:
        inf->adjust ( 6 );
        sup->adjust ( 7 );
        break;
    case 28:
        inf->adjust ( 6 );
        sup->adjust ( 8 );
        break;
    case 13:
        inf->adjust ( 7 );
        sup->adjust ( 1 );
        break;
    case 55:
        inf->adjust ( 7 );
        sup->adjust ( 2 );
        break;
    case 63:
        inf->adjust ( 7 );
        sup->adjust ( 3 );
        break;
    case 22:
        inf->adjust ( 7 );
        sup->adjust ( 4 );
        break;
    case 36:
        inf->adjust ( 7 );
        sup->adjust ( 5 );
        break;
    case 37:
        inf->adjust ( 7 );
        sup->adjust ( 6 );
        break;
    case 30:
        inf->adjust ( 7 );
        sup->adjust ( 7 );
        break;
    case 49:
        inf->adjust ( 7 );
        sup->adjust ( 8 );
        break;
    case 10:
        inf->adjust ( 8 );
        sup->adjust ( 1 );
        break;
    case 54:
        inf->adjust ( 8 );
        sup->adjust ( 2 );
        break;
    case 60:
        inf->adjust ( 8 );
        sup->adjust ( 3 );
        break;
    case 41:
        inf->adjust ( 8 );
        sup->adjust ( 4 );
        break;
    case 19:
        inf->adjust ( 8 );
        sup->adjust ( 5 );
        break;
    case 61:
        inf->adjust ( 8 );
        sup->adjust ( 6 );
        break;
    case 38:
        inf->adjust ( 8 );
        sup->adjust ( 7 );
        break;
    case 58:
        inf->adjust ( 8 );
        sup->adjust ( 8 );
        break;
    }
}

#include "hexagram.moc"
